#include <iostream>
#include <string>
#include <cstdlib>
#include <unistd.h>
#include <signal.h>
#include <sys/types.h>

using namespace std;

// 打印程序使用方法
void Usage(string proc)
{
    cout << "Usage:\n\t" << proc << " signum pid\n\n";
}

// 信号处理函数
// signo: 接收到的信号编号
void myhandler(int signo)
{
    cout << "process get a signal: " << signo <<endl;
    // exit(1); // 可以选择在收到信号后退出
}

int main(int argc, char *argv[])
{
    // 注册信号处理函数，捕获SIGABRT信号(signal 6)
    signal(SIGABRT, myhandler);
    
    int cnt = 0;
    while (true)
    {
        // 每秒打印一次进程PID
        cout << "I am a process, pid: " << getpid() << endl;
        sleep(1);
        cnt++;
        
        // 每2秒可以触发以下信号（取消注释任意一个）
        if(cnt % 2 == 0) 
        {
            //kill(getpid(), 2);    // 向自己发送SIGINT信号
            //raise(2);             // 向自己发送SIGINT信号的另一种方式
            //abort();              // 发送SIGABRT信号
            //kill(getpid(), 6);    // 向自己发送SIGABRT信号
        }
    }

    // 以下是命令行工具部分，可以向指定进程发送信号
    /*
    // 检查参数个数
    if(argc != 3)
    {
        Usage(argv[0]);
        exit(1);
    }
    // 获取命令行参数
    int signum = stoi(argv[1]);    // 要发送的信号编号
    pid_t pid = stoi(argv[2]);     // 目标进程PID

    // 发送信号
    int n = kill(pid, signum);
    if(n == -1)
    {
        perror("kill");
        exit(2);
    }
    */

    return 0;
}

/*
// 另一个版本的main函数，注册多个信号处理
int main()
{
    // 注册单个信号
    // signal(SIGINT, myhandler);  // 处理ctrl+c
    // signal(3, myhandler);       // 处理信号3
    // signal(19, myhandler);      // 处理信号19
    
    // 注册所有常规信号(1-31)
    // for(int i = 1; i <= 31; i++)
    // {
    //     signal(i, myhandler);
    // }

    // 主循环
    // while(true)
    // {
    //     cout << "I am a crazy process : " << getpid() << endl;
    //     sleep(1);
    // }
}
*/